package com.umeox.moto.common.utils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonSyntaxException;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Type;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class GsonUtils {

    /**
     * <code>fromObject</code>
     *
     * @param object
     * @return
     * @throws JSONException
     * @description: (字符串或者对象转化为JSONObject)
     */
    public static JSONObject fromObject(Object object) throws JSONException {
        GsonBuilder gsonb = new GsonBuilder();
        gsonb.setDateFormat("yyyy-MM-dd hh:mm:ss");
        gsonb.registerTypeAdapter(Date.class,
                new DateTimeTypeAdapter());
        Gson gson = gsonb.create();
        return new JSONObject(gson.toJson(object));
    }

    public static JSONArray objectToArray(Object object) throws JSONException {
        GsonBuilder gsonb = new GsonBuilder();
        Gson gson = gsonb.create();
        gsonb.setDateFormat("yyyy-MM-dd HH:mm:ss");
        return new JSONArray(gson.toJson(object));
    }

    /**
     * <code>toBean</code>
     *
     * @param <T>
     * @param jsonString
     * @param beanclass
     * @return
     * @description: (json字符串转化为类)
     */
    public static <T> T toBean(String jsonString, Class<T> beanclass) {
        GsonBuilder gsonb = new GsonBuilder();
        gsonb.setDateFormat("yyyy-MM-dd HH:mm:ss");
        Gson gson = gsonb.create();
        return gson.fromJson(jsonString, beanclass);
    }

    public static <T> T toBean(String jsonString, Type t) {
        GsonBuilder gsonb = new GsonBuilder();
        gsonb.setDateFormat("yyyy-MM-dd HH:mm:ss");
        Gson gson = gsonb.create();
        try {
            return gson.fromJson(jsonString, t);
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * <code>toBean</code>
     *
     * @param <T>
     * @param object
     * @param beanclass
     * @return
     * @description: (json对象转化为类)
     */
    public static <T> T toBean(JSONObject object, Class<T> beanclass) {
        return toBean(object.toString(), beanclass);
    }

    /**
     * 把字符串转换成JSON对象
     *
     * @param string
     * @return
     */
    public static JSONObject toJSONObject(String string) {
        try {
            return new JSONObject(string);
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String toJson(Object obj) {
        GsonBuilder gsonb = new GsonBuilder();
        gsonb.setDateFormat("yyyy-MM-dd HH:mm:ss");
        Gson gson = gsonb.setPrettyPrinting().create();
        return gson.toJson(obj);
    }

    /**
     * 把字符串转换成JSON数组对象
     *
     * @param string
     * @return
     */
    public static JSONArray toJSONArray(String string) {
        try {
            return new JSONArray(string);
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }

    }

    public static Map json2Object(String jsonStr) {
        JSONObject jsonObj = null;
        try {
            jsonObj = new JSONObject(jsonStr);
            Iterator<String> nameItr = jsonObj.keys();
            String name;
            Map<String, Object> outMap = new HashMap<String, Object>();
            while (nameItr.hasNext()) {
                name = nameItr.next();
                outMap.put(name, jsonObj.getString(name));
            }
            return outMap;
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }

    }

    private static class DateTimeTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
        @Override
        public Date deserialize(JsonElement json, Type t, JsonDeserializationContext arg2) throws JsonParseException {
            if (!(json instanceof JsonPrimitive)) {
                throw new JsonParseException("The date should be a string value");
            }
            try {
                Date date = DateUtils.SDF_YMDHMS.parse(json.getAsString());
                return new Date(date.getTime());
            } catch (ParseException e) {
                throw new JsonParseException(e);
            }
        }

        @Override
        public JsonElement serialize(Date ts, Type arg1, JsonSerializationContext arg2) {
            String dfString = DateUtils.SDF_YMDHMS.format(ts);
            return new JsonPrimitive(dfString);
        }
    }

    /**
     * @param json list的序列化字符串
     * @param <T>  T类型
     * @return List<T>
     */
    public static <T> List<T> toList(String json, Class<T> clazz) {
        List<T> list = new ArrayList<>();
        try {
            JsonArray array = new JsonParser().parse(json).getAsJsonArray();
            for (final JsonElement elem : array) {
                list.add(new Gson().fromJson(elem, clazz));
            }
        } catch (Exception e) {
            return null;
        }
        return list;
    }

}
